package com.liuyu.common.framework.spring.lifecycle;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.support.DefaultLifecycleProcessor;
import org.springframework.stereotype.Component;

/**
 * @ClassName SmartLifecycleTest
 * @Author: liuyu
 * @Date: Created in 2021/8/16 23:45
 * @Version:
 * @Modified By:
 */
@Component
@Slf4j
public class SmartLifecycleTest implements SmartLifecycle {
    /**
     * Start this component.
     * <p>Should not throw an exception if the component is already running.
     * <p>In the case of a container, this will propagate the start signal to all
     * components that apply.
     * @see SmartLifecycle#isAutoStartup()
     */
    @Override
    public void start() {
        log.error("SmartLifecycle start");
    }

    /**
     * Stop this component, typically in a synchronous fashion, such that the component is
     * fully stopped upon return of this method. Consider implementing {@link SmartLifecycle}
     * and its {@code stop(Runnable)} variant when asynchronous stop behavior is necessary.
     * <p>Note that this stop notification is not guaranteed to come before destruction:
     * On regular shutdown, {@code Lifecycle} beans will first receive a stop notification
     * before the general destruction callbacks are being propagated; however, on hot
     * refresh during a context's lifetime or on aborted refresh attempts, a given bean's
     * destroy method will be called without any consideration of stop signals upfront.
     * <p>Should not throw an exception if the component is not running (not started yet).
     * <p>In the case of a container, this will propagate the stop signal to all components
     * that apply.
     * @see SmartLifecycle#stop(Runnable)
     * @see DisposableBean#destroy()
     */
    @Override
    public void stop() {
        log.error("SmartLifecycle stop");
    }

    /**
     * Check whether this component is currently running.
     * <p>In the case of a container, this will return {@code true} only if <i>all</i>
     * components that apply are currently running.
     * @return whether the component is currently running
     */
    @Override
    public boolean isRunning() {
        log.error("SmartLifecycle isRunning");
        return true;
    }

    /**
     * Returns {@code true} if this {@code Lifecycle} component should get
     * started automatically by the container at the time that the containing
     * {@link ApplicationContext} gets refreshed.
     * <p>A value of {@code false} indicates that the component is intended to
     * be started through an explicit {@link #start()} call instead, analogous
     * to a plain {@link Lifecycle} implementation.
     * <p>The default implementation returns {@code true}.
     * @see #start()
     * @see #getPhase()
     * @see LifecycleProcessor#onRefresh()
     * @see ConfigurableApplicationContext#refresh()
     */
    @Override
    public boolean isAutoStartup() {
        log.error("SmartLifecycle isAutoStartup");
        return SmartLifecycle.super.isAutoStartup();
    }

    /**
     * Indicates that a Lifecycle component must stop if it is currently running.
     * <p>The provided callback is used by the {@link LifecycleProcessor} to support
     * an ordered, and potentially concurrent, shutdown of all components having a
     * common shutdown order value. The callback <b>must</b> be executed after
     * the {@code SmartLifecycle} component does indeed stop.
     * <p>The {@link LifecycleProcessor} will call <i>only</i> this variant of the
     * {@code stop} method; i.e. {@link Lifecycle#stop()} will not be called for
     * {@code SmartLifecycle} implementations unless explicitly delegated to within
     * the implementation of this method.
     * <p>The default implementation delegates to {@link #stop()} and immediately
     * triggers the given callback in the calling thread. Note that there is no
     * synchronization between the two, so custom implementations may at least
     * want to put the same steps within their common lifecycle monitor (if any).
     * @see #stop()
     * @see #getPhase()
     * @param callback
     */
    @Override
    public void stop(Runnable callback) {
        log.error("SmartLifecycle stop");
        SmartLifecycle.super.stop(callback);
    }

    /**
     * Return the phase that this lifecycle object is supposed to run in.
     * <p>The default implementation returns {@link #DEFAULT_PHASE} in order to
     * let {@code stop()} callbacks execute after regular {@code Lifecycle}
     * implementations.
     * @see #isAutoStartup()
     * @see #start()
     * @see #stop(Runnable)
     * @see DefaultLifecycleProcessor#getPhase(Lifecycle)
     */
    @Override
    public int getPhase() {
        log.error("SmartLifecycle getPhase");
        return SmartLifecycle.super.getPhase();
    }
}
